{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from gs_quant.session import Environment, GsSession\n",
    "from gs_quant.instrument import IRSwaption\n",
    "from gs_quant.markets.portfolio import Portfolio\n",
    "from gs_quant.markets import PricingContext\n",
    "from gs_quant.risk import RollFwd\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# external users should substitute their client id and secret; please skip this step if using internal jupyterhub\n",
    "GsSession.use(Environment.PROD, client_id=None, client_secret=None, scopes=('run_analytics',))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# basic usage of RollFwd scenario\n",
    "eur1y10y = IRSwaption('Pay', '10y', 'EUR', expiration_date='1y')\n",
    "\n",
    "# care needs to be taken when creating relative trades like the one above.  \n",
    "# If you don't resolve the trade, the resolution of the trade parameters will be done with \n",
    "# reference to the active pricing context.  Under the RollFwd scenario this means that\n",
    "# if you don't resolve the trade will be a different trade when priced under the rollfwd scenario.\n",
    "eur1y10y.resolve()\n",
    "\n",
    "# Roll forward 1 month\n",
    "rollfwd_scenario = RollFwd(date='1m',holiday_calendar='LDN')\n",
    "with rollfwd_scenario:\n",
    "    fwd_price = eur1y10y.price()\n",
    "\n",
    "print('Base price:     {:,.2f}'.format(eur1y10y.price()))\n",
    "print('Scenario price: {:,.2f}'.format(fwd_price))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# show how the option value will roll down moving forward 66 business days assuming either fwds \n",
    "# or spot rates are realised.\n",
    "\n",
    "short_swaption = IRSwaption('Pay', '5y', 'USD', expirationDate='6m', notionalAmount=1e8)\n",
    "short_swaption.resolve()\n",
    "\n",
    "prices = []\n",
    "roll_spot_prices = []\n",
    "with PricingContext():\n",
    "    for bus_days in range(66):\n",
    "        with RollFwd(date=f'{bus_days}b', holiday_calendar= 'NYC', realise_fwd=True):\n",
    "            prices.append(short_swaption.price())\n",
    "        with RollFwd(date=f'{bus_days}b', holiday_calendar= 'NYC', realise_fwd=False):\n",
    "            roll_spot_prices.append(short_swaption.price())\n",
    "\n",
    "pd.Series([p.result() for p in prices], dtype=np.dtype(float)).plot(figsize=(10, 6),\n",
    "                                                                    title=\"Swaption Price Forward in Time\", \n",
    "                                                                    label='roll to fwd')\n",
    "pd.Series([rp.result() for rp in roll_spot_prices], dtype=np.dtype(float)).plot(figsize=(10, 6), \n",
    "                                                       label='roll to spot')\n",
    "plt.xlabel('Business Days from Pricing Date')\n",
    "plt.ylabel('PV')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a grid of expiry by tenor swaptions showing the pv under the rollfwd scenario minus the base pv.\n",
    "def calc_risk_matrix(ccy, strike, pay_rec, date, roll_to_fwds, expiries, tenors):\n",
    "    portfolio = Portfolio([IRSwaption(pay_rec, tenor, ccy,\n",
    "                                      expiration_date=expiry, strike=strike, name='{}_{}'.format(expiry, tenor)) \n",
    "                          for expiry in expiries for tenor in tenors])\n",
    "    portfolio.resolve()\n",
    "    with RollFwd(date=date, holiday_calendar='LDN', realise_fwd=roll_to_fwds):\n",
    "        rollfwd_results = portfolio.price()\n",
    "    \n",
    "    base_results = portfolio.price()\n",
    "    \n",
    "    rollfwd_records = [(rollfwd_results[t.name]-base_results[t.name], t.name.split('_')[0], t.name.split('_')[1]) for t in portfolio]\n",
    "    rollfwd_df = pd.DataFrame(rollfwd_records, columns=['Value', 'Expiry', 'Tenor'])\n",
    "    \n",
    "    pivot_df = rollfwd_df.pivot_table(values='Value', index='Expiry', columns='Tenor')\n",
    "    return pivot_df[tenors].reindex(expiries)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ccy = 'EUR'\n",
    "strike = 'ATM'\n",
    "pay_rec = 'Pay'  # or 'Receive' or 'Straddle'\n",
    "date = '1m'  # enter relative or actual date\n",
    "roll_to_fwds = True\n",
    "expiries = ['1m', '2m', '3m', '6m', '9m', '1y', '18m', '2y', '3y', '5y', '7y', '10y']\n",
    "tenors = ['1y', '2y', '3y', '5y', '7y', '10y', '15y', '20y', '25y', '30y']\n",
    "\n",
    "calc_risk_matrix(ccy, strike, pay_rec, date, roll_to_fwds, expiries, tenors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  },
  "pycharm": {
   "stem_cell": {
    "cell_type": "raw",
    "metadata": {
     "collapsed": false
    },
    "source": []
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
